/// 学习资料 https://dart.cn/codelabs/iterables

void main() {
  Iterable<String> list = ['Abc', 'Redis', 'Spring'];
  // for-in 遍历元素
  for (final e in list) {
    print("element = ${e}");
  }

  // 迭代器可以通过first和last访问第一个和最后一个元素
  print("first element = ${list.first}");
  print("last element ${list.last}");

  // 找到符合条件的 第一个和最后一个元素
  var firstWhere = list.firstWhere((element) => element.contains("e"));
  print("first where = $firstWhere");
  assert(firstWhere == "Redis");
  var lastWhere = list.lastWhere((element) => element.contains("A"));
  assert(lastWhere == "Abc");
  print("last where = ${lastWhere}");
  // 可以使用函数块
  assert(list.firstWhere((element) {
        return element.length == 6;
      }) ==
      "Spring");

  // 使用单独定义的函数，predicate有“谓语、断言”之意，可以理解为“判定条件”
  bool predicate(el) {
    return el.length == 6;
  }

  assert(list.firstWhere(predicate) == "Spring");

  // 当找不到元素时，可以使用orElse
  // 查找“other”是不存在元素，返回“Default”
  assert(list.firstWhere((element) => element.contains("other"),
          orElse: () => "Default") ==
      "Default");
  // 异常”No element“
  // assert(list.firstWhere((element) => element.contains("other")) == "None");

  // singleWhere 只找一个符合条件的元素 找到多个元素时会StateError
  assert(list.singleWhere((element) => element.contains("Redis")) == "Redis");

  // 检查-当所有元素符合条件返回true
  assert(list.every((element) => element.length >= 3));
  // 检查-当有一个符合条件就返回true
  assert(list.any((element) => element.contains("Redis")));
  // 找到符合条件的元素
  assert(list.where((e) => e.length > 3).join(",") == "Redis,Spring");

  /// takeWhile skipWhile
  const numbers = [1, 3, -2, 0, 4, 5];
  // 逐个检查符合条件的元素，获取符合条件的元素，当遇到不符合条件时结束查找并返回已找到的元素的集合。
  assert(numbers.takeWhile((value) => value != 0).join(",") == "1,3,-2");
  // 逐个检查符合条件的元素，跳过符合条件的元素，遇到不符合条件元素时，返回之后的所有元素的集合。
  assert(numbers.skipWhile((value) => value != 0).join(",") == "0,4,5");
  // 跳过不等于-2的，当遇到-2, 就返回之后的所有元素
  // 跳过不等于-2的元素，如果设置为value==-2，第一个元素时就false了，此时返回整个
  var join = numbers.skipWhile((value) => value != -2).join(",");
  assert(join == "-2,0,4,5");
  // 用for-in 循环实现skipWhile
  List<int> rList = [];
  bool skip = false;
  for (var value1 in numbers) {
    if (value1 == -2) {
      skip = true;
    }
    if (skip) {
      rList.add(value1);
    }
  }
  assert(rList.join(",")=="-2,0,4,5");

  /// map
  assert(numbers.map((e) => e*2).join(",")=="2,6,-4,0,8,10");
}
